package br.com.damazzy.negocio.servico;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.ibm.icu.text.SimpleDateFormat;

import br.com.damazzy.dto.RetornoDTO;
import br.com.damazzy.negocio.entidade.Pessoa;
import br.com.damazzy.negocio.entidade.Produto;
import br.com.damazzy.negocio.entidade.TipoPagamento;
import br.com.damazzy.negocio.entidade.Usuario;
import br.com.damazzy.negocio.entidade.Venda;
import br.com.damazzy.negocio.entidade.VendaProduto;
import br.com.damazzy.negocio.persistencia.dao.DamazzyDaoFactory;
import br.com.damazzy.negocio.persistencia.dao.PessoaDao;
import br.com.damazzy.negocio.persistencia.dao.ProdutoDao;
import br.com.damazzy.negocio.persistencia.dao.TipoPagamentoDao;
import br.com.damazzy.negocio.persistencia.dao.UsuarioDao;
import br.com.damazzy.negocio.persistencia.dao.VendaDao;
import br.com.damazzy.negocio.persistencia.dao.VendaProdutoDao;
import br.com.damazzy.negocio.servico.conversor.DamazzyConversor;
import br.com.damazzy.vo.VendaVO;

public class ServicoVenda implements ServicoCrudDamazzy<VendaVO, RetornoDTO>, DamazzyConversor<Venda, VendaVO> {
	
	private static final String LISTA = "lista";
	private static final String LISTA_VENDEDORES = "listaVendedores";
	private static final String LISTA_COMPRADORES = "listaCompradores";
	private static final String LISTA_TIPOS_PAGAMENTO = "listaTiposPagamento";
	private static final String LISTA_PESSOAS = "listaPessoas";
	private static final String VO = "vo";
	private static final String PRODUTO_VO = "produtoVO";
	private static final String LISTA_PRODUTOS = "listaProdutos";
	
	private static SimpleDateFormat sdfData = new SimpleDateFormat("dd/MM/yyyy");
	private static SimpleDateFormat sdfDataHora = new SimpleDateFormat("dd/MM/yyyy - HH:mm:ss");
	
	private PessoaDao pessoaDao = DamazzyDaoFactory.getInstance().criarPessoaDao();
	private TipoPagamentoDao tipoPagamentoDao = DamazzyDaoFactory.getInstance().criarTipoPagamentoDao();
	private VendaDao vendaDao = DamazzyDaoFactory.getInstance().criarVendaDao();
	private ProdutoDao produtoDao = DamazzyDaoFactory.getInstance().criarProdutoDao();
	private UsuarioDao usuarioDao = DamazzyDaoFactory.getInstance().criarUsuarioDao();
	private VendaProdutoDao vendaProdutoDao = DamazzyDaoFactory.getInstance().criarVendaProdutoDao();
	
	public RetornoDTO obterDefinicoesSelecao() throws Exception {
		
		RetornoDTO dto = new RetornoDTO();
		
		List<TipoPagamento> tiposPagamento = tipoPagamentoDao.listar();
		List<VendaVO> tiposPagamentoVO = converterTipoPagamentoEntidadeVO(tiposPagamento);
		
		dto.dados.put(LISTA_TIPOS_PAGAMENTO, tiposPagamentoVO);
		
		return dto;
	}
	
	public RetornoDTO obterDefinicoesAcompanharVendas() throws Exception {
		
		RetornoDTO dto = new RetornoDTO();
	
		List<Usuario> vendedores = usuarioDao.listar();
		List<VendaVO> vendedoresVO = converterPessoaVendedorEntidadeVO(vendedores);
		
		List<Pessoa> compradores = pessoaDao.listar();
		List<VendaVO> compradoresVO = converterPessoaCompradorEntidadeVO(compradores);
		
		dto.dados.put(LISTA_VENDEDORES, vendedoresVO);
		dto.dados.put(LISTA_COMPRADORES, compradoresVO);
		
		return dto;
	}
	
	public RetornoDTO obterDefinicoes() throws Exception {
		
		RetornoDTO dto = obterDefinicoesSelecao();
		
		return dto;
	}

	public RetornoDTO alterar(VendaVO vo) throws Exception {
		
		RetornoDTO dto = new RetornoDTO();
		
		Venda venda = converterVOEntidade(vo);
		venda = vendaDao.alterar(venda);
		
		VendaVO voAlterada = converterEntidadeVO(venda);
		
		dto.dados.put(VO, voAlterada);
		
		return dto;
	}

	public RetornoDTO excluir(VendaVO vo) throws Exception {
		
		Venda venda = converterVOEntidade(vo);
		vendaDao.excluir(venda.getIdVenda());
		
		return new RetornoDTO();
	}

	public RetornoDTO incluir(VendaVO vo) throws Exception {
			
		Venda venda = converterVOEntidade(vo);
		vendaDao.incluir(venda);
		
		return new RetornoDTO();
	}

	public RetornoDTO obter(VendaVO vo) throws Exception {
		
		RetornoDTO dto = new RetornoDTO();
			
		Venda venda = converterVOEntidade(vo);
		venda = vendaDao.obter(venda.getIdVenda());
		
		VendaVO vendaVO = converterEntidadeVO(venda);
		
		dto.dados.put(VO, vendaVO);
		
		return dto;
	}

	public RetornoDTO pesquisar(VendaVO vo) throws Exception {
		
		RetornoDTO dto = new RetornoDTO();
			
		Venda vendaFiltro = converterVOEntidade(vo);
		List<Venda> vendas = vendaDao.pesquisar(vendaFiltro);
		List<VendaVO> vos = converterEntidadeVO(vendas);
		
		dto.dados.put(LISTA, vos);
		
		return dto;
	}
	
	public RetornoDTO realizarVenda(VendaVO vo) throws Exception {
		
		RetornoDTO dto = new RetornoDTO();
		Venda venda = converterVOEntidade(vo);
		venda.setDataHora(new Date());
		
		vendaDao.realizarVenda(venda);
		
		return dto;
	}
	
	public RetornoDTO obterProduto(VendaVO vo) throws Exception {
		
		RetornoDTO dto = new RetornoDTO();
		
		Produto produto = produtoDao.obterPorCodigo(vo.getCodigoProduto());
		
		VendaVO produtoVO = converterEntidadeVO(produto);
		
		dto.dados.put(PRODUTO_VO, produtoVO);
		
		return dto;
	}
	
	public RetornoDTO obterProdutosPorVenda(VendaVO vo) throws Exception {
		
		RetornoDTO dto = new RetornoDTO();
		
		List<VendaProduto> vendaProdutos = vendaProdutoDao.obterProdutosPorIdVenda(Long.parseLong(vo.getIdVenda()));
		List<VendaVO> produtosVO = converterListaEntidadeVO(vendaProdutos);
		
		dto.dados.put(LISTA_PRODUTOS, produtosVO);
		
		return dto;
	}
	
	public RetornoDTO pesquisarPessoas(VendaVO vo) throws Exception {
		
		RetornoDTO dto = new RetornoDTO();
		
		Pessoa p = converterVOEntidadePessoa(vo);
		
		List<Pessoa> pessoas = pessoaDao.pesquisar(p, Boolean.TRUE);
		List<VendaVO> vos = converterPessoaCompradorEntidadeVO(pessoas);
		
		dto.dados.put(LISTA_PESSOAS, vos);
		
		return dto;
	}
	
	public Venda converterVOEntidade(VendaVO vo) throws Exception {
		
		Venda venda = new Venda();
		Pessoa p;
		
		venda.setIdVenda(vo.getIdVenda() != null ? new Long(vo.getIdVenda()) : null);
		
		if (vo.getIdPessoaVendedor() != null) {
			p = new Pessoa();
			p.setIdPessoa(new Long(vo.getIdPessoaVendedor()));
			venda.setPessoaVendedor(p);
		}
		
		if (vo.getIdPessoaComprador() != null) {
			p = new Pessoa();
			p.setIdPessoa(new Long(vo.getIdPessoaComprador()));
			venda.setPessoaComprador(p);
		}
		
		if (vo.getIdTipoPagamento() != null) {
			TipoPagamento tp = new TipoPagamento();
			tp.setIdTipoPagamento(new Integer(vo.getIdTipoPagamento()));
			venda.setTipoPagamento(tp);
		}
		
		venda.setDataHora(vo.getDataHora() != null ? sdfData.parse(vo.getDataHora()) : null);
		venda.setDesconto(vo.getDesconto() != null ? new Integer(vo.getDesconto()) : null);
		venda.setValorTotal(vo.getValorTotal() != null ? new BigDecimal(vo.getValorTotal()) : null);
		venda.setValorTotalDesconto(vo.getValorTotalDesconto() != null ? new BigDecimal(vo.getValorTotalDesconto()) : null);
		venda.setQtdParcelas(vo.getQtdParcelas() != null ? new Integer(vo.getQtdParcelas()) : null);
		venda.setBolExcluida(vo.getBolExcluida() != null ? new Boolean(vo.getBolExcluida()) : null);
		
		List<VendaProduto> listaVendaProdutos = new ArrayList<VendaProduto>();
		
		if (vo.getListaProdutos() != null) {
			for (VendaVO vendaProduto : vo.getListaProdutos()) {
				listaVendaProdutos.add(converterVOEntidadeVendaProduto(vendaProduto));
			}
			
			venda.setListaVendaProdutos(listaVendaProdutos);
		}
		
		return venda;
	}
	
	public VendaProduto converterVOEntidadeVendaProduto(VendaVO vo) throws Exception {
		
		VendaProduto vendaProduto = new VendaProduto();
		Venda venda = new Venda();
		Produto produto = new Produto();
		
		venda.setIdVenda(vo.getIdVenda() != null ? new Long(vo.getIdVenda()) : null);
		produto.setIdProduto(vo.getIdProduto() != null ? new Long(vo.getIdProduto()) : null);
		produto.setQuantidadeEstoque(vo.getQuantidadeEstoque() != null ? Integer.parseInt(vo.getQuantidadeEstoque()) : null);
		vendaProduto.setQtdProdutos(vo.getQuantidadeProduto() != null ? Integer.parseInt(vo.getQuantidadeProduto().trim()) : null);
		
		vendaProduto.setVenda(venda);
		vendaProduto.setProduto(produto);
		
		return vendaProduto;
	}
	
	public VendaVO converterEntidadeVO(Venda venda) throws Exception {
		
		VendaVO vo = new VendaVO();
		
		vo.setIdVenda(venda.getIdVenda().toString());
		vo.setIdPessoaVendedor(venda.getPessoaVendedor().getIdPessoa().toString());
		vo.setNomeVendedor(venda.getPessoaVendedor().getNome());
		vo.setIdPessoaComprador(venda.getPessoaComprador().getIdPessoa().toString());
		vo.setNomeComprador(venda.getPessoaComprador().getNome());
		vo.setIdTipoPagamento(venda.getTipoPagamento().getIdTipoPagamento().toString());
		vo.setDescTipoPagamento(venda.getTipoPagamento().getDescTipoPagamento());
		vo.setDesconto(venda.getDesconto() != null ? venda.getDesconto().toString() : "");
		vo.setDataHora(sdfDataHora.format(venda.getDataHora()));
		vo.setValorTotal(venda.getValorTotal().toString());
		vo.setValorTotalDesconto(venda.getValorTotalDesconto().toString());
		vo.setQtdParcelas(venda.getQtdParcelas().toString());
		vo.setBolExcluida(venda.getBolExcluida().toString());
		
		return vo;
	}
	
	public VendaVO converterEntidadeVO(Usuario u) throws Exception {
		
		VendaVO vo = new VendaVO();
		
		vo.setIdPessoaVendedor(u.getPessoa().getIdPessoa().toString());
		vo.setNomeVendedor(u.getPessoa().getNome());
		
		return vo;
	}
	
	public VendaVO converterEntidadeVO(Pessoa p) throws Exception {
		
		VendaVO vo = new VendaVO();
		
		vo.setIdPessoaComprador(p.getIdPessoa().toString());
		vo.setNomeComprador(p.getNome());
		
		return vo;
	}
	
	public Pessoa converterVOEntidadePessoa(VendaVO vo) throws Exception {
		
		Pessoa p = new Pessoa();
		
		p.setIdPessoa(vo.getIdPessoaComprador() != null ? Long.parseLong(vo.getIdPessoaComprador()) : null);
		p.setNome(vo.getNomeComprador());
		
		return p;
	}
	
	public VendaVO converterEntidadeVO(TipoPagamento tp) throws Exception {
		
		VendaVO vo = new VendaVO();
		
		vo.setIdTipoPagamento(tp.getIdTipoPagamento().toString());
		vo.setDescTipoPagamento(tp.getDescTipoPagamento());
		
		return vo;
	}
	
	public VendaVO converterEntidadeVO(Produto produto) throws Exception {
		
		VendaVO vo = null;
		
		if (produto != null) {
			
			vo = new VendaVO();
			vo.setIdProduto(produto.getIdProduto().toString());
			vo.setCodigoProduto(produto.getCodigo());
			vo.setNomeProduto(produto.getNome());
			vo.setValorProduto(produto.getValor().toString());
			vo.setTamanhoProduto(produto.getTamanho().getCodigo());
			vo.setDescTipoProduto(produto.getTipoProduto().getDescricao());
			vo.setQuantidadeEstoque(produto.getQuantidadeEstoque().toString());
		}
		
		return vo;
	}
	
	private List<VendaVO> converterEntidadeVO(List<Venda> vendas) throws Exception {
		
		List<VendaVO> vos = new ArrayList<VendaVO>();
		
		for (Venda venda : vendas) {
			vos.add(converterEntidadeVO(venda));
		}
		
		return vos;
	}
	
	private List<VendaVO> converterPessoaVendedorEntidadeVO(List<Usuario> vendedores) throws Exception {
		
		List<VendaVO> vos = new ArrayList<VendaVO>();
		
		for (Usuario u : vendedores) {
			vos.add(converterEntidadeVO(u));
		}
		
		return vos;
	}
	
	private List<VendaVO> converterPessoaCompradorEntidadeVO(List<Pessoa> compradores) throws Exception {
		
		List<VendaVO> vos = new ArrayList<VendaVO>();
		
		for (Pessoa p : compradores) {
			vos.add(converterEntidadeVO(p));
		}
		
		return vos;
	}
	
	private List<VendaVO> converterTipoPagamentoEntidadeVO(List<TipoPagamento> tiposPagamento) throws Exception {
		
		List<VendaVO> vos = new ArrayList<VendaVO>();
		
		for (TipoPagamento tp : tiposPagamento) {
			vos.add(converterEntidadeVO(tp));
		}
		
		return vos;
	}
	
	private List<VendaVO> converterListaEntidadeVO(List<VendaProduto> vendaProdutos) throws Exception {
		
		List<VendaVO> vos = new ArrayList<VendaVO>();
		VendaVO vo;
		
		for (VendaProduto vp : vendaProdutos) {
			vo = converterEntidadeVO(vp.getProduto());
			vo.setQtdProdutos(vp.getQtdProdutos().toString());
			vos.add(vo);
		}
		
		return vos;
	}
}
